package com.ruoyi.common.utils.http;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;
import org.springframework.lang.Nullable;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 翰林学士
 * @version 1.0
 * @email RenZetong@Outlook.com
 * Create by 2025-02-07 16:16:39
 * 一个模仿 Axios 风格的 Java HTTP 工具类。
 */
public class Axios {

    private static Logger logger = LoggerFactory.getLogger(Axios.class);

    private static final RestTemplate restTemplate = new RestTemplate();

    private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS" );

    /**
     * 发送 GET 请求
     *
     * @param url          请求的URL
     * @param params       URL 参数
     * @param headers      请求头
     * @param responseType 响应体类型
     * @param <T>          泛型参数
     * @return 响应实体
     */
    public static <T> ResponseEntity<T> get(String url, Map<String, ?> params, HttpHeaders headers, Class<T> responseType) {
        // 如果请求头为null则使用自定义请求头
        if (headers == null) {
            headers = generateChromeLikeHeaders();
        }
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
        if (params != null) {
            for (Map.Entry<String, ?> entry : params.entrySet()) {
                builder.queryParam(entry.getKey(), entry.getValue());
            }
        }
        HttpEntity<?> entity = new HttpEntity<>(headers);
        return restTemplate.exchange(builder.toUriString(), HttpMethod.GET, entity, responseType);
    }

    /**
     * 发送 POST 请求，数据以 JSON 格式发送
     *
     * @param url          请求的URL
     * @param data         请求体数据
     * @param headers      请求头
     * @param responseType 响应体类型
     * @param <D>          数据类型
     * @param <T>          泛型参数
     * @return 响应实体
     */
    public static <D, T> ResponseEntity<T> postJson(String url, D data, @Nullable HttpHeaders headers, Class<T> responseType) {
        // 如果请求头为null则使用自定义请求头
        if (headers == null) {
            headers = generateChromeLikeHeaders();
        }
        HttpEntity<D> entity = new HttpEntity<>(data, headers);
        return restTemplate.postForEntity(url, entity, responseType);
    }

    /**
     * 发送 POST 请求，数据以表单形式发送
     *
     * @param url          请求的URL
     * @param formData     表单数据
     * @param headers      请求头
     * @param responseType 响应体类型
     * @param <T>          泛型参数
     * @return 响应实体
     */
    public static <T> ResponseEntity<T> postForm(String url, MultiValueMap<String, String> formData, HttpHeaders headers, Class<T> responseType) {
        // 如果请求头为null则使用自定义请求头
        if (headers == null) {
            headers = generateChromeLikeHeaders();
        }
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(formData, headers);
        return restTemplate.postForEntity(url, requestEntity, responseType);
    }

    /**
     * 创建自定义请求头
     *
     * @param customHeaders 自定义请求头键值对
     * @return HttpHeaders对象
     */
    public static HttpHeaders createHeaders(Map<String, String> customHeaders) {
        HttpHeaders headers = new HttpHeaders();
        if (customHeaders != null) {
            customHeaders.forEach(headers::set);
        }
        return headers;
    }

    /**
     * 生成类似谷歌浏览器的HttpHeaders。
     * <p>
     * 注意：实际应用中，User-Agent等信息可能会因为操作系统、浏览器版本等因素而不同。
     * 这里提供的只是一个通用的例子。
     */
    private static HttpHeaders generateChromeLikeHeaders() {
        HttpHeaders headers = new HttpHeaders();

        // 添加常见的请求头
        Map<String, String> commonHeaders = new HashMap<>();
        commonHeaders.put("Accept" , "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" );
        commonHeaders.put("Accept-Encoding" , "gzip, deflate, br" );
        commonHeaders.put("Accept-Language" , "en-US,en;q=0.9" );
        commonHeaders.put("Cache-Control" , "max-age=0" );
        commonHeaders.put("Connection" , "keep-alive" );
        commonHeaders.put("Upgrade-Insecure-Requests" , "1" );
        commonHeaders.put("User-Agent" , "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36" );

        // 将自定义的请求头添加到HttpHeaders对象中
        commonHeaders.forEach(headers::set);

        return headers;
    }

    // Post数据请求示例
    public static void main(String[] args) throws Exception {
        // 准备URL
        String url = "https://jsonplaceholder.typicode.com/posts";

        // 准备请求体数据
        Map<String, Object> postData = new HashMap<>();
        postData.put("title" , "foo" );
        postData.put("body" , "bar" );
        postData.put("userId" , 1);

        // 设置请求头
        HttpHeaders headers = Axios.createHeaders(new HashMap<String, String>() {{
            put("Content-Type" , "application/json" );
        }});

        // 发送POST请求并处理响应
        ResponseEntity<String> response = Axios.postJson(url, postData, headers, String.class);
        logger.info("响应码:{}" , response.getStatusCode());
        logger.info("响应头:{}" , response.getHeaders());
        logger.info("数据:{}" , response.getBody());
    }

    // Get请求示例
//    public static void main(String[] args) {
//        // 准备URL和参数
//        String url = "https://jsonplaceholder.typicode.com/posts";
//        Map<String, Object> params = new HashMap<>();
//        params.put("userId", 1);g
//
//        // 设置请求头
//        HttpHeaders headers = Axios.createHeaders(new HashMap<String, String>() {{
//            put("Accept", "application/json");
//        }});
//
//        // 发送GET请求并处理响应
//        ResponseEntity<String> response = Axios.get(url, params, headers, String.class);
//        logger.info("响应码:{}", response.getStatusCode());
//        logger.info("响应头:{}", response.getHeaders());
//        logger.info("数据:{}", response.getBody());
//    }
}